home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UHashTable.cp < prev    next >
Encoding:
Text File  |  1994-02-20  |  3.3 KB  |  171 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UHashTable.cp
  3.  
  4. #include "UHashTable.h"
  5. #include "StreamTools.h"
  6.  
  7. #pragma segment MyGroup
  8.  
  9. const short kHashByteMask = (1 << (    kHashBitShift)) - 1;
  10. const short kHashWordMask = (1 << (2 * kHashBitShift)) - 1;
  11.  
  12. const long kCurrentHashTableVersion = 1;
  13. const long kMinHashTableVersion = 1;
  14.  
  15. THashTable::THashTable()
  16. {
  17. }
  18.  
  19. pascal void THashTable::Initialize()
  20. {
  21.     inherited::Initialize();
  22. }
  23.  
  24. void THashTable::IHashTable()
  25. {
  26.     inherited::IObject();
  27. }
  28.  
  29. pascal void THashTable::Free()
  30. {
  31.     inherited::Free();
  32. }
  33.  
  34. void THashTable::DoRead(TStream *aStream)
  35. {
  36.     long version = aStream->ReadLong();
  37.     MyStreamCheckVersion(version, kMinHashTableVersion, kCurrentHashTableVersion, "THashTable");
  38.     Lock(true);
  39.     aStream->ReadBytes(fHashTable, kHashTableSize);
  40.     Lock(false);
  41. #if qDebug
  42.     SanityCheck();
  43. #endif
  44. }
  45.  
  46. void THashTable::DoWrite(TStream *aStream)
  47. {
  48.     aStream->WriteLong(kCurrentHashTableVersion);
  49.     Lock(true);
  50.     aStream->WriteBytes(fHashTable, kHashTableSize);
  51.     Lock(false);
  52. }
  53.  
  54. void THashTable::DoNeedDiskSpace(long &dataForkBytes)
  55. {
  56.     dataForkBytes += sizeof(long); // version
  57.     dataForkBytes += kHashTableSize;
  58. }
  59.  
  60. short THashTable::HashMessageID(char *p, long &len) // I don't know how effective this stuff is
  61. // p must point on '<' when called
  62. {
  63.     register unsigned long hash = 0;
  64. //    register unsigned char ch;
  65.     register unsigned long ch; // saves a lot of char -> long conversions
  66.     register long theLen = 0;
  67.     register unsigned char *up = (unsigned char*)p;
  68.     while (true) 
  69.     {
  70. #if 0
  71. // 1
  72.         ch = *up++;
  73.         if (ch <= 32)
  74.             break;
  75.         hash ^= ch << kHashBitShift;
  76.         theLen++;
  77.         if (ch == '>')
  78.             break;
  79. // 2
  80.         ch = *up++;
  81.         if (ch <= 32)
  82.             break;
  83.         hash ^= (ch & kHashByteMask);
  84.         theLen++;
  85.         if (ch == '>')
  86.             break;
  87. // 3
  88.         ch = *up++;
  89.         if (ch <= 32)
  90.             break;
  91.         hash ^= ch << (kHashBitShift / 2);
  92.         theLen++;
  93.         if (ch == '>')
  94.             break;
  95. #endif
  96. #define macroHashByte(x)        \
  97.         ch = *up++;                            \
  98.         if (ch <= 32)                        \
  99.             break;                                \
  100.         hash ^= ch << x;                \
  101.         theLen++;                                \
  102.         if (ch == '>')                    \
  103.             break;
  104. // end macro
  105.         macroHashByte(8);
  106.         macroHashByte(3);
  107.         macroHashByte(0);
  108.         macroHashByte(6);
  109.         macroHashByte(2);
  110.         macroHashByte(5);
  111.         macroHashByte(1);
  112.         macroHashByte(4);
  113.     }
  114.     len = theLen;
  115.     return short(kHashWordMask & hash);
  116. }
  117.  
  118. void THashTable::FillHashTable(ArrayIndex value)
  119. {
  120.     ArrayIndex *p = fHashTable;
  121.     for (short i = 0; i < kHashTableEntries; i++) 
  122.         *p++ = value; // faster than indexing all the time!
  123. #if qDebug
  124.     SanityCheck();
  125. #endif
  126. }
  127.  
  128. void THashTable::DebugDump(FILE *file)
  129. {
  130. #if qDebug
  131.     fprintf(stderr, "DebugDump of hashtable:\n");
  132.     for (ArrayIndex index = 0; index < kHashTableEntries; index++)
  133.     {
  134.         if (index % 20 == 0)
  135.             fprintf(file, "%4ld: ", index);
  136.         ArrayIndex hash = fHashTable[index];
  137.         if (hash == -1)
  138.             fprintf(file, "    -");
  139.         else
  140.             fprintf(file, "%5ld", hash);
  141.         if ((index + 1) % 20 == 0)
  142.             fprintf(file, "\n");
  143.     }
  144.     fprintf(file, "\n");
  145. #else
  146.     file = file;
  147. #endif
  148. }
  149.  
  150. Boolean THashTable::SanityCheck()
  151. {
  152.     Boolean isGood = true;
  153. #if qDebug
  154.     for (ArrayIndex index = 0; index < kHashTableEntries; index++)
  155.     {
  156.         long hash = fHashTable[index];
  157.         if (hash == -1)
  158.             continue;
  159.         if (hash < 0 || hash > 3000)
  160.         {
  161.             fprintf(stderr, "Wrong: THashTable::SanityCheck, bad value %ld with index %ld\n", hash, index);
  162.             isGood = false;
  163.         }
  164.     }
  165.     if (!isGood)
  166.         DebugDump(stderr);
  167. #endif
  168.     return isGood;
  169. }
  170.  
  171.